﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Reflection;

namespace WHC.OrderWater.Commons
{
    public class StartupHelper
    {
        static Mutex SingleInstanceMutex = null;

        public static bool AppAlreadyRunning(string app)
        {
            try
            {
                SingleInstanceMutex = Mutex.OpenExisting(app);
                return true;
            }
            catch (Exception)
            {
                SingleInstanceMutex = new Mutex(false, app);
            }
            finally
            {
                Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
            }
            return false;
        }

        public static void CleanupMutex()
        {
            Application_ApplicationExit(null, null);
        }

        static void Application_ApplicationExit(object sender, EventArgs e)
        {
            try
            {
                if (SingleInstanceMutex != null)
                {
                    SingleInstanceMutex.ReleaseMutex();
                }
            }
            catch (Exception)
            {
                // no recovery is required or possible.
            }
            finally
            {
                SingleInstanceMutex = null;
            }
        }

        static RegistryKey rkApp = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
        public static bool WillRunAtStartup(string app)
        {
            try
            {
                return string.Equals(rkApp.GetValue(app), Environment.CommandLine);
            }
            catch (Exception)
            {
                // failure indicates lack of permissions, lack of platform support.
                return false;
            }
        }

        public static void RunAtStartup(string app, bool shouldRun)
        {
            try
            {
                if (shouldRun)
                {
                    rkApp.SetValue(app, Environment.CommandLine);
                }
                else
                {
                    rkApp.DeleteValue(app, false);
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Unable to RunAtStartup: " + ex);
            }
        }

        #region 只运行一个实例

        /// <summary>
        ///  Process instance = StartupHelper.RunningInstance();
        /// if (instance == null)
        /// {
        ///     //正常启动的代码
        /// }
        /// else
        /// {
        ///      StartupHelper.HandleRunningInstance(instance);
        /// }
        /// </summary>
        /// <returns></returns>
        public static Process RunningInstance()
        {
            Process current = Process.GetCurrentProcess();
            Process[] processes = Process.GetProcessesByName(current.ProcessName);
            //遍历与当前进程名称相同的进程列表 
            foreach (Process process in processes)
            {
                //Ignore the current process 
                if (process.Id != current.Id)
                {
                    //Make sure that the process is running from the exe file. 
                    if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
                    {
                        //Return the other process instance. 
                        return process;
                    }
                }
            }
            return null;
        }

        public static void HandleRunningInstance(Process instance)
        {
            MessageUtil.ShowError("该应用系统已经在运行！");
            ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL); //调用api函数，正常显示窗口 
            SetForegroundWindow(instance.MainWindowHandle); //将窗口放置最前端。 
        }

        [DllImport("User32.dll")]
        private static extern bool ShowWindowAsync(System.IntPtr hWnd, int cmdShow);
        [DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(System.IntPtr hWnd);
        private const int WS_SHOWNORMAL = 1;
        #endregion 
    }
}
